﻿using System;

namespace Zinnia.EF.Test.Utility
{
    /// <summary>
    /// 反射帮助类
    /// </summary>
    public sealed class ReflectHelper
    {
        private static readonly Lazy<ReflectHelper> lazy = new Lazy<ReflectHelper>(() => new ReflectHelper());
        private ReflectHelper() { }
        public static ReflectHelper Instance { get { return lazy.Value; } }

        public object CreateInstance(Type type)
        {
            return type.Assembly.CreateInstance(type.FullName);
        }

        public T CreateInstance<T>(Type type)
        {
            return (T)CreateInstance(type);
        }

        /// <summary>
        /// 创建实例
        /// </summary>
        /// <typeparam name="T">实例对象</typeparam>
        /// <param name="assemblyName">程序集名称</param>
        /// <param name="typeName">实例对象类型</param>
        /// <returns></returns>
        public T CreateInstance<T>(string assemblyName, string typeName)
        {
            try
            {
                return CreateInstance<T>(assemblyName, typeName, null, null);
            }
            catch (Exception ex)
            {
                throw new Exception("While CreateInstance<T>(string assemblyName, string typeName) Occur Error", ex);
            }
        }
        /// <summary>
        /// 创建实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type_assembly">格式：type=type_assembly[0],assembly=type_assembly[1]</param>
        /// <returns></returns>
        public T CreateInstance<T>(string[] type_assembly)
        {
            try
            {
                return CreateInstance<T>(type_assembly[1], type_assembly[0]);
            }
            catch (Exception ex)
            {
                throw new Exception("While CreateInstance<T>(string[] type_assembly) Occur Error", ex);
            }
        }
        /// <summary>
        /// 创建实例
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="type_assembly">格式：type,assembly</param>
        /// <returns></returns>
        public T CreateInstance<T>(string type_assembly)
        {
            try
            {
                string[] type_assemblys = type_assembly.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                return CreateInstance<T>(type_assemblys);
            }
            catch (Exception ex)
            {
                throw new Exception("While CreateInstance<T>(string type_assembly) Occur Error", ex);
            }
        }
        /// <summary>
        /// 创建实例
        /// </summary>
        /// <typeparam name="T">实例对象</typeparam>
        /// <param name="assemblyName">程序集名称</param>
        /// <param name="typeName">实例对象类型</param>
        /// <param name="param">实例参数</param>
        /// <param name="typeParam">实例参数类型</param>
        /// <returns></returns>
        public T CreateInstance<T>(string assemblyName, string typeName, object[] param, Type[] typeParam)
        {
            try
            {
                System.Reflection.Assembly assembly = System.Reflection.Assembly.Load(assemblyName);
                Type t = assembly.GetType(typeName, false, true);
                System.Reflection.ConstructorInfo constructor = t.GetConstructor(typeParam);
                return (T)Activator.CreateInstance(constructor.DeclaringType, param);
            }
            catch (Exception ex)
            {
                throw new Exception("While CreateInstance<T>(string assemblyName, string typeName, object[] param, Type[] typeParam) Occur Error", ex);
            }
        }
    }
}
